﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using AutoMapper;
using ST.Application.MenuServices.Dtos;
using ST.Domain;
using ST.Domain.Entities;
using ST.Domain.IRepositories;

namespace ST.Application.MenuServices
{
    public class MenuService : IMenuService
    {
        private readonly IMapper _mapper;
        private readonly IMenuRepository _menuRepository;
        private readonly IRoleRepository _roleRepository;
        private readonly IUserRepository _userRepository;

        public MenuService(IMenuRepository menuRepository, IUserRepository userRepository,
            IRoleRepository roleRepository, IMapper mapper)
        {
            _menuRepository = menuRepository;
            _userRepository = userRepository;
            _roleRepository = roleRepository;
            _mapper = mapper;
        }

        public async Task<List<MenuDto>> GetAllListAsync()
        {
            var menus = await _menuRepository.GetAllListAsync();
            return _mapper.Map<List<MenuDto>>(menus.OrderBy(it => it.SerialNumber));
        }

        public async Task<PagedList<MenuDto>> GetMenusByParent(Guid parentId, int startPage, int pageSize)
        {
            var pageList = await _menuRepository.LoadPageListAsync(startPage, pageSize, o => o.ParentId == parentId,
                o => o.SerialNumber);
            return _mapper.Map<PagedList<MenuDto>>(pageList);
        }

        public async Task<bool> InsertAsync(MenuDto dto)
        {
            await _menuRepository.InsertAsync(_mapper.Map<Menu>(dto), false);
            return await _menuRepository.SaveAsync();
        }

        public async Task<bool> UpdateAsync(MenuDto dto)
        {
            await _menuRepository.UpdateAsync(_mapper.Map<Menu>(dto), false);
            return await _menuRepository.SaveAsync();
        }

        public async Task DeleteBatchAsync(List<Guid> ids)
        {
            await _menuRepository.DeleteAsync(o => ids.Contains(o.Id));
        }

        public async Task DeleteAsync(Guid id)
        {
            await _menuRepository.DeleteAsync(id);
        }

        public async Task<MenuDto> GetAsync(Guid id)
        {
            return _mapper.Map<MenuDto>(await _menuRepository.GetAsync(id));
        }

        /// <summary>
        ///     根据用户获取功能菜单
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns></returns>
        public async Task<List<MenuDto>> GetMenusByUser(Guid userId)
        {
            var result = new List<MenuDto>();
            var allMenus = await _menuRepository.GetAllListAsync(it => it.Type == 0);
            if (userId == Guid.Empty) //超级管理员
                return _mapper.Map<List<MenuDto>>(allMenus.OrderBy(o => o.SerialNumber));
            var user =await _userRepository.GetWithRoles(userId);
            if (user == null)
                return result;
            var userRoles = user.UserRoles;
            var menuIds = new List<Guid>();
            foreach (var role in userRoles)
                menuIds = menuIds.Union(_roleRepository.GetAllMenuListByRole(role.RoleId)).ToList();
            allMenus = allMenus.Where(it => menuIds.Contains(it.Id)).ToList();
            return _mapper.Map<List<MenuDto>>(allMenus);
        }
    }
}